package com.patternbox.eclipse.wizard;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.internal.runtime.Activator;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;
import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;



public class AddScenario extends WizardPage{

	private final String WIZARD_TITLE = "Add a new Scenario";
	private final String WIZARD_DESC = "Here you can add a new scenario to test the impact of your changes.";
	
	private Text titleText;
	private Text containerText;
	private Combo typesCombo;
	private Text descriptionText;
	
	public AddScenario(){
		super("wizardPage");
		setTitle(WIZARD_TITLE);
		setDescription(WIZARD_DESC);
		setPageComplete(false);
	}

	@Override
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
	    GridLayout layout = new GridLayout();
	    container.setLayout(layout);
	    layout.numColumns = 3;
	    layout.verticalSpacing = 9;
	    
	    // Loads the scenarios from the config file
	    ArrayList<String> types = new ArrayList<String>();
	    
	    Bundle pluginBundle = Activator.getDefault().getBundle("com.patternbox.eclipse.editor");
	
		URL scenariosFileUrl = pluginBundle.getEntry("/config/patternImpact.xml");		
	
		try{
			String scenariosFileURL = FileLocator.toFileURL(scenariosFileUrl).toString();		
		
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			
			// Load all the types of scenarios
			Document scenariosDoc = dBuilder.parse(scenariosFileURL);
			scenariosDoc.getDocumentElement().normalize();
			NodeList nodes = scenariosDoc.getElementsByTagName("scenario");
			// For each type of Scenario
			for (int i = 0; i < nodes.getLength(); i++) {
				Node node = nodes.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					Element element = (Element) node;
					types.add(getValue("id", element));
				}
			}		
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
	
	    
	    
	    //////////////////////////////////////////////////////////////////////////////////////
	    
	    Label label = new Label(container, SWT.NULL);
	    label.setText("Scenario Title");	    
	    
	    titleText = new Text(container, SWT.BORDER | SWT.SINGLE);
	    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
	    titleText.setLayoutData(gd);
	    titleText.addModifyListener(new ModifyListener() {
	         public void modifyText(ModifyEvent e) {
	            dialogChanged();
	         }
	      });
	    
	    label = new Label(container, SWT.NULL);
	    
	    //////////////////////////////////////////////////////////////////////////////////////
	    
	    label = new Label(container, SWT.NULL);
	    label.setText("Container");

	    containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
	    containerText.setLayoutData(gd);
	    containerText.addModifyListener(new ModifyListener() {
	    public void modifyText(ModifyEvent e) {
	            dialogChanged();
	         }
	    });

	    Button button = new Button(container, SWT.PUSH);
	    button.setText("Browse");
	    button.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent e) {
	           handleBrowse();
	         }
	    });
	    
	    //////////////////////////////////////////////////////////////////////////////////////
	    
	    label = new Label(container, SWT.NULL);
	    label.setText("Scenario Type");
	    
	    typesCombo = new Combo(container, SWT.BOLD | SWT.READ_ONLY);
	    for (int i = 0 ; i < types.size() ; i++){
	    	typesCombo.add(types.get(i),i);
	    }
	    typesCombo.select(0);
	    
	    label = new Label(container, SWT.NULL);
	    
	    //////////////////////////////////////////////////////////////////////////////////////
	    
	    label = new Label(container, SWT.NULL);
	    label.setText("Scenario Description");
	    
	    descriptionText = new Text(container, SWT.MULTI | SWT.BORDER | SWT.WRAP);
	    GridData descriptionGd = new GridData();
	    descriptionGd.widthHint = 300;
	    descriptionGd.heightHint = 75;
	    descriptionText.setLayoutData(descriptionGd);
	    
	    setControl(container);
	}
	
	private void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}
	
	private void handleBrowse(){
		ContainerSelectionDialog dialog =
				new ContainerSelectionDialog(
					getShell(),
					ResourcesPlugin.getWorkspace().getRoot(),
					false,
					"Select new file container");
			if (dialog.open() == ContainerSelectionDialog.OK) {
				Object[] result = dialog.getResult();
				if (result.length == 1) {
					containerText.setText(((Path) result[0]).toOSString());
				}
			}
	}
	
	private void dialogChanged() {
	
		if (getTitleName().length() == 0){
			updateStatus("Title is required!");
			return;
		}	
		
		if (getContainerName().length() == 0){
			updateStatus("Container is required");
			return;
		}
		
		if (!getContainerName().contains("\\Scenarios")){
			updateStatus("The Scenario must be saved in proyectRoot\\Scenarios");
			return;
		}
		
		if (fileExists()){
			updateStatus("The file already exists");
			return;
		}
		
		updateStatus(null);
	}
	
	public String getTitleName(){
		return titleText.getText();		
	}
	
	public String getContainerName(){
		return containerText.getText();		
	}
	
	public String getDescriptionName(){
		return descriptionText.getText();
	}
	
	public String getTypeName(){
		return typesCombo.getText();
	}

	public boolean fileExists(){
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(getContainerName()));
		IContainer container = (IContainer) resource;
		
		// Create the file if it doesn't exist
		final IFile file = container.getFile(new Path(getTitleName()+ ".sce"));
		try{
			if (file.exists()) {		
				return true;
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	private static String getValue(String tag, Element element) {
		NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
		Node node = (Node) nodes.item(0);
		return node.getNodeValue();
	}
	
}
